/* -----------------------------------------------------------------------------
 * PROJECT    : net.lwf
 * FILE       : NumberGenerator.java
 *
 * HISTORY:
 * Date          Author                        Description
 * ----------------------------------------------------------------------------- 
 * Nov 13, 2008       Raghu Sarraff			       Created
 */
package net.lwf.handler.util;

import java.util.ArrayList;
import java.util.List;

import net.lwf.number.util.RandomNumberGenerator;

import lwf.handler.entities.SequenceData;

/**
 * Type the class description here
 *  
 */
public class SequenceGenerator {

	//Configurable Parameters
	private static int REQ_SEQ_NUM = 10; 
	private static int REQ_QUESTIONS = 4;
	private static int SEQ_RANGE_START = 1;
	private static int SEQ_RANGE_END = 100;
	private static int MULTIPLE_SEQ_RANGE_START = 1;
	private static int MULTIPLE_SEQ_RANGE_END = 5;	
	private static int REQ_DIGITS = 1; 
	private static int MULTIPLE_RANGE_START = 1;
	private static int MULTIPLE_RANGE_END = 3; 
	//SequenceProcessHandler types
	private static String ARITHMATIC_SEQUENCE = "1";
	private static String GEOMETRIC_SEQUENCE = "2";
	private static String TRIANGULAR_SEQUENCE = "3";

	public static void main(String[] args) {
		SequenceData seq = generateSequnce("1");
		seq.print();
		
	}
	
	private static int getReqQuestions() {
		return RandomNumberGenerator.generate(1, REQ_QUESTIONS);
	}
	
	
	public static List<String> generateSequence(boolean reverse) {
    	int start = RandomNumberGenerator.generate(SEQ_RANGE_START, SEQ_RANGE_END);
    	int increment = RandomNumberGenerator.generate(REQ_DIGITS); //later specify the range
    	
    	if(reverse) {
    		int check = increment * REQ_SEQ_NUM;
    		if(start < check) {
    			start = check;
    		}    		
    		increment = -increment;
    	}
		List<String> lstNumbers = new ArrayList<String>();
		int nCounter = 1;
		int oldval = start;
		lstNumbers.add(String.valueOf(oldval));
		while(nCounter < REQ_SEQ_NUM) {
			oldval = oldval + increment;
			lstNumbers.add(String.valueOf(oldval));
			nCounter++;
		}
		return lstNumbers;
	}	
	public static List<String> generateMultiples(boolean reverse) {
    	int start = RandomNumberGenerator.generate(MULTIPLE_SEQ_RANGE_START, MULTIPLE_SEQ_RANGE_END);
    	int multiple = RandomNumberGenerator.generate(MULTIPLE_RANGE_START, MULTIPLE_RANGE_END); 		
		if(reverse) {
    		double check = Math.pow(multiple, REQ_SEQ_NUM);
    		if(start < check) {
    			start = (int) check;
    		}    		
		}

		List<String> lstNumbers = new ArrayList<String>();
		int nCounter = 1;
		int oldval = start;
		lstNumbers.add(String.valueOf(oldval));
		while(nCounter < REQ_SEQ_NUM) {
			if(!reverse) {
				oldval = oldval * multiple;
			}
			else {
				oldval = oldval / multiple;
			}
			lstNumbers.add(String.valueOf(oldval));
			nCounter++;
		}
		return lstNumbers;
	}	

	public static List<String> generateTriangularSequence(boolean reverse) {
		List<String> lstNumbers = new ArrayList<String>();
		int start = RandomNumberGenerator.generate(SEQ_RANGE_START, SEQ_RANGE_END);
		int nCounter = 0;
    	if(reverse) {
    		while(start - 51 < 1) {
    			start = RandomNumberGenerator.generate(SEQ_RANGE_START, SEQ_RANGE_END);
    		}    		
    		nCounter = -10;
    	}
		int oldval = start;
		lstNumbers.add(String.valueOf(oldval));
		for(int i=0; i<REQ_SEQ_NUM; i++) {
			nCounter++;
			oldval = oldval + nCounter;
			lstNumbers.add(String.valueOf(oldval));			
		}
		return lstNumbers;
	} //generateTriangularSequence	
	
	public static SequenceData generateSequnce(String seqtype) {
		int forreverse = RandomNumberGenerator.generate(1, 2);

        String seqname = "Arithmatic Sequence";
    	List<String> lstData = null;
    	if(seqtype.equals(GEOMETRIC_SEQUENCE)) {
    		seqname = "Geometric Sequence";
    		//if(forreverse == 1) {
    		//	lstData = generateMultiples(true);
    		//}
    		//else {
    			lstData = generateMultiples(false);	
    		//}
    	}
    	else if(seqtype.equals(TRIANGULAR_SEQUENCE)) {
    		seqname = "Triangular Sequence";
    		if(forreverse == 1) {
    			lstData = generateTriangularSequence(true);
    		}
    		else {
    			lstData = generateTriangularSequence(false);	
    		}    		
    	}
    	else {
    		//Arithmatic SequenceProcessHandler
    		if(forreverse == 1) {
    			lstData = generateSequence(true);
    		}
    		else {
    			lstData = generateSequence(false);	
    		}    		
    	}    	

		int requiredQs = getReqQuestions(); //configurable
		SequenceData seqdata = null;

		int indexloc = RandomNumberGenerator.generate(1, REQ_SEQ_NUM - REQ_QUESTIONS);
		String answerstring = "";
		for (int i = 0; i < requiredQs; i++) {

			answerstring += (String) lstData.get(indexloc);
			if (i + 1 < requiredQs) {
				answerstring += ",";
			}

			lstData.remove(indexloc);
			lstData.add(indexloc, "?");

			indexloc++;
		}

//		String questionstring = "";
//		for (int i = 0; i < lstData.size(); i++) {
//			questionstring += lstData.get(i);
//			if (i + 1 < lstData.size()) {
//				questionstring += ", ";
//			}
//		}
		seqdata = new SequenceData(seqname, lstData, answerstring);
		return seqdata;
    }	
	
	
}

